﻿using UnityEngine;
using System.Collections;
using System;
using System.Collections.Generic;
using UnityEngine.Networking;
using UnityEngine.Events;

public class EzAssetManager : Singleton<EzAssetManager>
{
    private static readonly object _syslock = new object();
    private Dictionary<string, GameObject> dicGameObject;//缓存
    private Dictionary<string, AssetBundle> dicAssetBundle;
    private Dictionary<string, Material> dicMaterial;
    private Dictionary<string, UnityEngine.Object> dicObject;
    private Dictionary<string, AssetBundleRequest> dicAssetBundleRequest;
    public EzAssetManager()
    {
        dicGameObject = new Dictionary<string, GameObject>();
        dicAssetBundle = new Dictionary<string, AssetBundle>();
        dicObject = new Dictionary<string, UnityEngine.Object>();
        dicMaterial = new Dictionary<string, Material>();
        dicAssetBundleRequest = new Dictionary<string, AssetBundleRequest>();
    }

    /// <summary>
    /// 从Resources中生成物体
    /// </summary>
    /// <param name="ResourcesPath"></param>
    /// <returns></returns>
    public GameObject CreateObjFromRes(string ResourcesPath)
    {
        string PerfabeName = GetResourcePath(ResourcesPath);
        return GameObject.Instantiate(dicGameObject[PerfabeName]);
    }

    public GameObject CreateObjFromRes(string ResourcesPath, Transform parent)
    {
        string PerfabeName = GetResourcePath(ResourcesPath);
        return UnityEngine.Object.Instantiate(dicGameObject[PerfabeName], parent);
    }

    public GameObject CreateObjFromRes(string ResourcesPath, Vector3 Posion, Quaternion rotation)
    {
        string PerfabeName = GetResourcePath(ResourcesPath);
        return UnityEngine.Object.Instantiate(dicGameObject[PerfabeName], Posion, rotation);
    }

    public GameObject CreateObjFromRes(string ResourcesPath, Vector3 position, Quaternion rotation, Transform parent)
    {
        string PerfabeName = GetResourcePath(ResourcesPath);
        return UnityEngine.Object.Instantiate(dicGameObject[PerfabeName], position, rotation, parent);
    }


    private string GetResourcePath(string ResourcesPath)
    {
        string[] names = ResourcesPath.Split('/');

        string PerfabeName;
        if (names.Length == 0)
        {
            PerfabeName = ResourcesPath;
        }
        else
        {
            PerfabeName = names[names.Length - 1];
        }
        if (dicGameObject.ContainsKey(PerfabeName))//如果对象池里有这个文件
        {
            //Debug.Log("从对象池中加载预制体");
        }
        else
        {
            GameObject obj = Resources.Load<GameObject>(ResourcesPath);
            dicGameObject.Add(PerfabeName, obj);
        }
        return PerfabeName;
    }

    /// <summary>
    /// 加载AB包中的某个物体到场景中
    /// </summary>
    /// <param name="ULR">AB包地址</param>
    /// <param name="PerfabePath"></param>
    /// <returns></returns>
    IEnumerator CreatePerfabeFromeABAsyToScence<T>(string ULR, string PerfabePath)
    {
#if UNIYU_2018
         UnityWebRequest WebRequest = UnityWebRequestAssetBundle.GetAssetBundle(ULR);
#else
        UnityWebRequest WebRequest = UnityWebRequestAssetBundle.GetAssetBundle(ULR);
#endif
        yield return WebRequest.SendWebRequest();
        AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(WebRequest);
        var loadAsset = bundle.LoadAssetAsync<T>(PerfabePath);
        yield return loadAsset;
        GameObject obj = loadAsset.asset as GameObject;
    }

    IEnumerator CreatePerfabeFromeABAsyToScence(string ULR, string PerfabePath, UnityAction<GameObject> action)
    {
#if UNIYU_2018
         UnityWebRequest WebRequest = UnityWebRequestAssetBundle.GetAssetBundle(ULR);
#else
        UnityWebRequest WebRequest = UnityWebRequestAssetBundle.GetAssetBundle(ULR);
#endif
        yield return WebRequest.SendWebRequest();
        AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(WebRequest);
        AssetBundleRequest loadAsset = bundle.LoadAssetAsync(PerfabePath);
        yield return loadAsset;
        GameObject tempObj = GameObject.Instantiate(loadAsset.asset as GameObject);
        action(tempObj);
    }

    /// <summary>
    /// 加载AB包异步
    /// </summary>
    /// <param name="ULR"></param>
    /// <param name="PerfabePath"></param>
    /// <param name="action"></param>
    /// <returns></returns>
    public IEnumerator LoadABFromAsy(string ULR, string PerfabePath, UnityAction<AssetBundleRequest> action)
    {
        if (dicAssetBundleRequest.ContainsKey(ULR + PerfabePath))
        {
            action(dicAssetBundleRequest[ULR + PerfabePath]);
        }
        else
        {
#if UNIYU_2018
         UnityWebRequest WebRequest = UnityWebRequestAssetBundle.GetAssetBundle(ULR);
#else
            UnityWebRequest WebRequest = UnityWebRequestAssetBundle.GetAssetBundle(ULR);
#endif
            yield return WebRequest.SendWebRequest();
            AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(WebRequest);
            AssetBundleRequest loadAsset = bundle.LoadAssetAsync<GameObject>(PerfabePath);
            action(loadAsset);
            dicAssetBundleRequest.Add(ULR + PerfabePath, loadAsset);
        }
    }

    
    //同步加载Resources资源
    public T Load<T>(string name) where T : UnityEngine.Object
    {
        T res = Resources.Load<T>(name);
        if (res is GameObject)
        {
            return GameObject.Instantiate(res);
        }
        else
        {
            return res;
        }
    }

    //异步加载资源  Resource
    public void LoadAsy<T>(string name, UnityEngine.Events.UnityAction<T> action) where T : UnityEngine.Object
    {
        EzMonoManager.Instance.StartCoroutine(ResLoadReallyLoadAsync(name, action));
    }

    ///同步加载资源
    public void LoadABObjAsy(string URL, string PrefabeName, UnityEngine.Events.UnityAction<AssetBundleRequest> action)
    {
        EzMonoManager.Instance.StartCoroutine(LoadABFromAsy(URL, PrefabeName, action));
    }

    private IEnumerator ResLoadReallyLoadAsync<T>(string name, UnityEngine.Events.UnityAction<T> action) where T : UnityEngine.Object
    {
        ResourceRequest res = Resources.LoadAsync(name);
        yield return res;
        if (res.asset is GameObject)
        {
            action(GameObject.Instantiate(res.asset) as T);
        }
        else
        {
            action(res.asset as T);
        }
    }

    /// <summary>
    ///同步加载AB包
    /// </summary>
    /// <param name="PerfabeName">AB包名</param>
    /// <param name="ABPath">AB包路径</param>
    /// <returns></returns>
    public T LoadABGameObject<T>(string ABPath, string PrefabeName) where T : UnityEngine.Object
    {
        AssetBundle assetBundle = AssetBundle.LoadFromFile(ABPath);
        T asset = assetBundle.LoadAsset<T>(PrefabeName);
        if (asset is GameObject)
        {
            return GameObject.Instantiate(asset);
        }
        return asset;
    }
}

